function W = thinPlateSpline(source, target, sigma)

if size(source, 1) ~= size(target, 1)
    error('source and target do not match', 'source and target do not match');
end

[nPoints dim] = size(source);
if nargin < 3
    K = thinPlateFunc(sqrt(dist2(source, source)));
else
    K = thinPlateFunc(sqrt(dist2(source, source)), sigma);
end
Q = [ones(nPoints, 1) source];
L = [K Q; Q' zeros(dim+1, dim+1)];
X = [target; zeros(dim+1, dim)];
W = (inv(L) * X)';
